package com.chendx.store.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chendx.model.cart.vo.CartVo;
import com.chendx.model.common.dtos.ResponseResult;
import com.chendx.model.common.enums.AppHttpCodeEnum;
import com.chendx.model.goods.pojo.Pref;
import com.chendx.model.goods.pojo.Sku;
import com.chendx.model.goods.pojo.Spu;
import com.chendx.model.order.dto.OrderDto;
import com.chendx.model.order.pojo.Order;
import com.chendx.model.order.pojo.OrderItem;
import com.chendx.model.order.vo.OrderNotice;
import com.chendx.model.order.vo.OrderVo;
import com.chendx.model.user.pojo.User;
import com.chendx.model.user.pojo.UserPref;
import com.chendx.store.common.constants.ampq.AMQPConstants;
import com.chendx.store.common.constants.cart.CartConstants;
import com.chendx.store.common.constants.goods.GoodsConstants;
import com.chendx.store.common.constants.order.OrderConstants;
import com.chendx.store.common.entity.IdWorker;
import com.chendx.store.order.feign.GoodsFeign;
import com.chendx.store.order.mapper.OrderItemMapper;
import com.chendx.store.order.mapper.OrderMapper;
import com.chendx.store.order.service.CartService;
import com.chendx.store.order.service.OrderService;
import com.chendx.store.utils.AppThreadLocalUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.alibaba.fastjson.JSON.parseObject;

/**
 * Created by chendx on 2022/4/19.
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    private CartService cartService;
    @Autowired
    private GoodsFeign goodsFeign;
    @Autowired
    private OrderItemMapper orderItemMapper;
    @Autowired
    private IdWorker idWorker;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private Environment env;

    @Override
    public ResponseResult addCartOrder(OrderDto dto) {
        User user = AppThreadLocalUtils.get();
        if (user == null || user.getId() == null || user.getUsername() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        String username = user.getUsername();
        if (dto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        if (StringUtils.isEmpty(dto.getReceiverAddress())
                || StringUtils.isEmpty(dto.getReceiverContact())
                || StringUtils.isEmpty(dto.getReceiverMobile())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.RECEIVER_IS_ERROR);
        }
        Pref pref = null;
        UserPref userPref = null;
        int totalMoney = 0; //总金额
        int preMoney = 0; //优惠券金额
        int payMoney = 0; //实付金额
        int totalNum = 0; //订单商品总数量
        ResponseResult responseResult = cartService.loadCheckedCartList();
        if (responseResult == null || responseResult.getData() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.SKU_IS_DELETE);
        }
        List<CartVo> cartVos = (List<CartVo>) responseResult.getData(); //获取选中的商品
        //购物车分类金额，用来分类优惠券类型
        Map<Integer, IntSummaryStatistics> cartVoMap =
                cartVos.stream().collect(Collectors.groupingBy(CartVo::getCategoryId3,
                        Collectors.summarizingInt(CartVo::getMoney)));
        String id = idWorker.nextId() + "";
        //订单明细列表
        for (CartVo cartVo : cartVos) {
            Sku sku = goodsFeign.findSkuById(Long.valueOf(cartVo.getSkuId()));
            if (sku == null) {
                return ResponseResult.errorResult(AppHttpCodeEnum.SKU_NOT_EXIST);
            }
            OrderItem orderItem = new OrderItem();
            orderItem.setId(idWorker.nextId() + "");
            orderItem.setCategoryId1(cartVo.getCategoryId1());
            orderItem.setCategoryId2(cartVo.getCategoryId2());
            orderItem.setCategoryId3(cartVo.getCategoryId3());
            orderItem.setSpuId(Long.valueOf(cartVo.getSpuId()));
            orderItem.setSkuId(Long.valueOf(cartVo.getSkuId()));
            orderItem.setPrice(sku.getPrice());
            orderItem.setNum(cartVo.getNum());
            orderItem.setMoney(sku.getPrice() * orderItem.getNum());
            orderItem.setOrderId(id);
            orderItem.setName(cartVo.getName());
            orderItem.setMoney(cartVo.getMoney());
            orderItem.setPayMoney(cartVo.getPayMoney());
            orderItem.setImage(cartVo.getImage());
            orderItem.setWeight(cartVo.getWeight());
            orderItem.setIsReturn(OrderConstants.ORDERITEM_IS_NOT_RETURN);
            orderItemMapper.insert(orderItem);
            goodsFeign.decrCount(orderItem);

            totalMoney += orderItem.getMoney();
            totalNum += orderItem.getNum();
            cartService.deleteChecked();
        }
        //优惠券价格处理
        if (!StringUtils.isEmpty(dto.getPrefId())) {
            ResponseResult prefRes = goodsFeign.one(dto.getPrefId());
            if (prefRes == null || prefRes.getData() == null) {
                return ResponseResult.errorResult(AppHttpCodeEnum.PREF_NOT_EXIST);
            }
            //优惠券信息
            pref = parseObject(JSON.toJSONString(prefRes.getData()), Pref.class);
            //用户是否拥有该优惠券
            Object o = redisTemplate.boundHashOps(CartConstants.RECEIVER_PREF + username).get(dto.getPrefId());
            if (o == null) {
                return ResponseResult.errorResult(AppHttpCodeEnum.USER_NOT_PREF);
            }
            userPref = parseObject(String.valueOf(o), UserPref.class);
            for (Integer categoryId : cartVoMap.keySet()) {
                int buyMoney = (int) cartVoMap.get(categoryId).getSum();
                //优惠券是否被使用
                if (userPref.getStatus().equals(GoodsConstants.USER_PREF_NOT_USE)) {
                    //未被使用，商品是否适用于该优惠券
                    if (pref.getCateId().equals(categoryId) && buyMoney >= pref.getBuyMoney()) {
                        //打折券
                        if (pref.getType().equals("3")) {
                            preMoney += buyMoney - buyMoney * pref.getPreMoney() / 1000;
                        } else if (pref.getType().equals("1")) {
                            //满减不可叠加
                            preMoney += pref.getPreMoney();
                        } else if (pref.getType().equals("2")) {
                            //满减可叠加券
                            preMoney += (totalMoney / pref.getBuyMoney()) * pref.getBuyMoney();
                        }
                        //获取商品明细计算单个商品明细所需支付的金额
                        List<OrderItem> orderItems =
                                orderItemMapper.selectList(Wrappers.<OrderItem>lambdaQuery().eq(OrderItem::getOrderId, id).eq(OrderItem::getCategoryId3, categoryId));
                        IntSummaryStatistics statistics = orderItems.stream().collect(Collectors.summarizingInt(OrderItem::getMoney));
                        //获取单个分类所有商品所需支付的金额
                        long sumMoney = statistics.getSum();
                        //百分比 用来计算所有百分比是否 等于1
                        double vs = 0;
                        for (int i = 0; i < orderItems.size(); i++) {
                            OrderItem orderItem = orderItems.get(i);
                            BigDecimal bigDecimal = new BigDecimal((float) orderItem.getMoney() / sumMoney);
                            double v = bigDecimal.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                            vs += v;
                            //判断所有比例加起来是否等于1
                            if (i == orderItems.size() - 1) {
                                if (1 - vs != 0) {
                                    v = 1 - vs + v;
                                }
                            }
                            //单商品明细优惠的金额
                            double itemPreMoney = v * preMoney;
                            double itemPayMoney = orderItem.getMoney() - itemPreMoney;
                            orderItem.setPayMoney((int) itemPayMoney);
                            orderItemMapper.updateById(orderItem);
                        }
                    }
                } else {
                    return ResponseResult.errorResult(AppHttpCodeEnum.PREF_NOT_EXIST);
                }
            }
        }
        payMoney = totalMoney - preMoney;
        //封装订单order信息
        Order order = new Order();
        order.setId(id);
        order.setReceiverContact(dto.getReceiverContact());
        order.setReceiverMobile(dto.getReceiverMobile());
        order.setReceiverAddress(dto.getReceiverAddress());
        order.setPayType(dto.getPayType());
        order.setTotalMoney(totalMoney);
        order.setPreMoney(preMoney);
        order.setTotalNum(totalNum);
        order.setPostFee(0);
        order.setPayMoney(payMoney);
        order.setCreateTime(new Date());
        order.setUsername(username);
        order.setBuyerMessage("");
        order.setSourceType("5");
        order.setOrderStatus("0");
        order.setPayStatus("0");
        order.setConsignStatus("0");
        order.setIsDelete("0");
        if (StringUtils.isEmpty(dto.getPrefId())) {
            order.setPrefId("0");
        } else {
            order.setPrefId(dto.getPrefId());
        }
        save(order);
        //修改使用的优惠券状态
         if (userPref != null){
            userPref.setStatus("1");
            userPref.setUseTime(new Date());
            redisTemplate.boundHashOps(CartConstants.RECEIVER_PREF + username).put(userPref.getPrefId(), JSON.toJSONString(userPref));
        }

        //发送rabbit消息
        convertAndSend(order.getId());
        redisTemplate.boundHashOps(OrderConstants.ORDERLIST).put(order.getId(), JSON.toJSONString(order));
        return ResponseResult.okResult(order);
    }

    /**
     * 使用商品优惠券的优惠金额
     *
     * @param id
     * @return
     */
    @Override
    public ResponseResult afterPrePrice(String id) {
        User user = AppThreadLocalUtils.get();
        if (user == null || user.getId() == null || user.getUsername() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        String username = user.getUsername();
        Integer preMoney = 0;
        Integer totalMoney = 0;
        Object obj = redisTemplate.boundHashOps(GoodsConstants.PREF_COUPON).get(id);
        if (obj == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PREF_NOT_EXIST);
        }
        Pref pref = JSON.parseObject(String.valueOf(obj), Pref.class);
        Object o = redisTemplate.boundHashOps(CartConstants.RECEIVER_PREF + username).get(id);
        if (o == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.USER_NOT_PREF);
        }
        UserPref userPref = JSON.parseObject(String.valueOf(o), UserPref.class);

        ResponseResult responseResult = cartService.loadCheckedCartList();
        if (responseResult == null || responseResult.getData() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.SKU_IS_DELETE);
        }
        List<CartVo> cartVos = (List<CartVo>) responseResult.getData(); //获取选中的商品
        //购物车分类金额，用来分类优惠券类型
        Map<Integer, IntSummaryStatistics> cartVoMap =
                cartVos.stream().collect(Collectors.groupingBy(CartVo::getCategoryId3,
                        Collectors.summarizingInt(CartVo::getMoney)));
        for (Integer categoryId : cartVoMap.keySet()) {
            int buyMoney = (int) cartVoMap.get(categoryId).getSum();
            if (userPref.getStatus().equals(GoodsConstants.USER_PREF_NOT_USE)) {
                if (pref.getCateId().equals(categoryId) && buyMoney >= pref.getBuyMoney()) {
                    if (pref.getType().equals("3")) {
                        preMoney += buyMoney - buyMoney * pref.getPreMoney() / 1000;
                    }
                    if (pref.getType().equals("1")) {
                        preMoney += pref.getPreMoney();
                    }
                    if (pref.getType().equals("2")) {
                        preMoney += (totalMoney / pref.getBuyMoney()) * pref.getBuyMoney();
                    }
                }
            } else {
                return ResponseResult.errorResult(AppHttpCodeEnum.PREF_NOT_EXIST);
            }
        }
        return ResponseResult.okResult(preMoney);
    }

    @Override
    public ResponseResult addOrder(OrderDto dto) {
        User user = AppThreadLocalUtils.get();
        if (user == null || user.getId() == null || user.getUsername() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        String username = user.getUsername();
        if (dto == null || StringUtils.isEmpty(dto.getSkuId())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        if (StringUtils.isEmpty(dto.getReceiverAddress())
                || StringUtils.isEmpty(dto.getReceiverContact())
                || StringUtils.isEmpty(dto.getReceiverMobile())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.RECEIVER_IS_ERROR);
        }
        if (StringUtils.isEmpty(String.valueOf(dto.getNum()))) {
            dto.setNum(1);
        }
        String skuId = dto.getSkuId();
        Integer totalNum = dto.getNum();
        Sku sku = goodsFeign.findSkuById(Long.valueOf(dto.getSkuId()));
        if (sku == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.SKU_NOT_EXIST);
        }
        if (sku.getNum() < dto.getNum()){
            return ResponseResult.errorResult(AppHttpCodeEnum.NO_STOCK_COUNT);
        }
        Spu spu = goodsFeign.findById(sku.getSpuId());
        if (spu == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.SPU_NOT_EXIST);
        }
        String id = idWorker.nextId() + ""; //订单order的id
        Pref pref = null;
        int totalMoney = sku.getPrice() * totalNum;
        int preMoney = 0; //优惠券金额
        //获取商品信息
        OrderItem orderItem = new OrderItem();
        orderItem.setId(idWorker.nextId() + ""); //订单明细id
        orderItem.setSkuId(Long.valueOf(skuId)); //skuId
        orderItem.setSpuId(Long.valueOf(sku.getSpuId())); //spuId
        orderItem.setCategoryId1(spu.getCategory1Id()); //分类id
        orderItem.setCategoryId2(spu.getCategory2Id());
        orderItem.setCategoryId3(sku.getCategoryId());
        orderItem.setName(sku.getName()); //title
        orderItem.setNum(totalNum); //数量
        orderItem.setImage(sku.getImage()); //图片
        orderItem.setWeight(sku.getWeight() * totalNum);
        orderItem.setPrice(sku.getPrice()); //单个商品金额
        orderItem.setMoney(totalMoney); //商品金额
        orderItem.setOrderId(id); //设置订单id
        orderItem.setIsReturn("0");
        ResponseResult responseResult = goodsFeign.decrCount(orderItem);
        if (responseResult == null || responseResult.getCode() != 0){
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);
        }
        //优惠券价格处理
        UserPref userPref = null;
        if (!StringUtils.isEmpty(dto.getPrefId())) {
            ResponseResult prefRes = goodsFeign.one(dto.getPrefId());
            if (prefRes == null || prefRes.getData() == null) {
                return ResponseResult.errorResult(AppHttpCodeEnum.PREF_NOT_EXIST);
            }
            //优惠券信息
            pref = parseObject(JSON.toJSONString(prefRes.getData()), Pref.class);
            //用户是否拥有该优惠券
            Object o = redisTemplate.boundHashOps(CartConstants.RECEIVER_PREF + username).get(dto.getPrefId());
            if (o == null) {
                return ResponseResult.errorResult(AppHttpCodeEnum.USER_NOT_PREF);
            }
            userPref = parseObject(String.valueOf(o), UserPref.class);
            //优惠券是否被使用
            if (userPref.getStatus().equals(GoodsConstants.USER_PREF_NOT_USE)) {
                //未被使用，商品是否适用于该优惠券
                if (pref.getCateId().equals(sku.getCategoryId()) && totalMoney >= pref.getBuyMoney()) {
                    //打折券
                    if (pref.getType().equals("3")) {
                        preMoney += totalMoney - totalMoney * pref.getPreMoney() / 1000;
                    } else if (pref.getType().equals("2")) {
                        //满减可叠加券
                        preMoney += (totalMoney / pref.getBuyMoney()) * pref.getBuyMoney();
                    } else if (pref.getType().equals("1")) {
                        //满减不可叠加
                        preMoney += pref.getPreMoney();
                    }
                }
            } else {
                return ResponseResult.errorResult(AppHttpCodeEnum.PREF_NOT_EXIST);
            }
        }
        int payMoney = totalMoney - preMoney;
        orderItem.setPayMoney(payMoney);
        orderItemMapper.insert(orderItem);
        //封装订单order信息
        Order order = new Order();
        order.setId(id);
        order.setReceiverContact(dto.getReceiverContact());
        order.setReceiverMobile(dto.getReceiverMobile());
        order.setReceiverAddress(dto.getReceiverAddress());
        order.setPayType(dto.getPayType());
        order.setTotalMoney(totalMoney);
        order.setPreMoney(preMoney);
        order.setTotalNum(totalNum);
        order.setPostFee(0);
        order.setPayMoney(payMoney);
        order.setCreateTime(new Date());
        order.setUsername(username);
        order.setBuyerMessage("");
        order.setSourceType("5");
        order.setOrderStatus("0");
        order.setPayStatus("0");
        order.setConsignStatus("0");
        order.setIsDelete("0");
        if (org.springframework.util.StringUtils.isEmpty(dto.getPrefId())) {
            order.setPrefId("0");
        } else {
            order.setPrefId(dto.getPrefId());
        }
        save(order);
        //修改使用的优惠券状态
        if (userPref != null){
            userPref.setStatus("1");
            userPref.setUseTime(new Date());
            redisTemplate.boundHashOps(CartConstants.RECEIVER_PREF + username).put(userPref.getPrefId(), JSON.toJSONString(userPref));
        }
        //发送rabbit消息
        convertAndSend(order.getId());
        redisTemplate.boundHashOps(OrderConstants.ORDERLIST).put(order.getId(), JSON.toJSONString(order));
        return ResponseResult.okResult(order);
    }

    @Override
    public ResponseResult pay(OrderDto dto) {
        User user = AppThreadLocalUtils.get();
        if (user == null || user.getId() == null || user.getUsername() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        String username = user.getUsername();
        if (dto == null || StringUtils.isEmpty(dto.getOrderId())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        Order order = null;
        Object o = redisTemplate.boundHashOps(OrderConstants.ORDERLIST).get(dto.getOrderId());
        if (o == null) {
            order = getById(dto.getOrderId());
            if (order == null) {
                return ResponseResult.errorResult(AppHttpCodeEnum.ORDER_NOT_EXIST);
            }
        } else {
            order = JSON.parseObject(String.valueOf(o), Order.class);
        }
        String payStatus = order.getPayStatus();
        String orderStatus = order.getOrderStatus();
        if (payStatus.equals("1") || orderStatus.equals("1")) {
            return ResponseResult.errorResult(AppHttpCodeEnum.ORDER_NOT_EXIST);
        }
        if (payStatus.equals("3") || orderStatus.equals("3")) {
            return ResponseResult.errorResult(AppHttpCodeEnum.ORDER_CLOSED);
        }
        if (payStatus.equals("2")) {
            return ResponseResult.errorResult(AppHttpCodeEnum.ORDER_PAY_FAIL);
        }
        order.setPayStatus("1");
        order.setPayTime(new Date());
        updateById(order);
        redisTemplate.boundHashOps(OrderConstants.ORDERLIST).delete(dto.getOrderId());

        //TODO 发送消息
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult loadUserAllOrder() {
        User user = AppThreadLocalUtils.get();
        if (user == null || user.getId() == null || user.getUsername() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        String username = user.getUsername();
        List<Order> orderList = list(Wrappers.<Order>lambdaQuery().eq(Order::getUsername, username));
        return ResponseResult.okResult(orderList);
    }

    @Override
    public ResponseResult loadOrderPage(OrderDto dto) {
        User user = AppThreadLocalUtils.get();
        if (user == null || user.getId() == null || user.getUsername() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        String username = user.getUsername();
        if (dto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        if (!org.springframework.util.StringUtils.isEmpty(username)) {
            queryWrapper.eq(Order::getUsername, username);
        }
        if (!org.springframework.util.StringUtils.isEmpty(dto.getOrderStatus())) {
            queryWrapper.eq(Order::getOrderStatus, dto.getOrderStatus());
        }
        if (!org.springframework.util.StringUtils.isEmpty(dto.getPayStatus())) {
            queryWrapper.eq(Order::getPayStatus, dto.getPayStatus());
        }
        if (!org.springframework.util.StringUtils.isEmpty(dto.getConsignStatus())) {
            queryWrapper.eq(Order::getConsignStatus, dto.getConsignStatus());
        }
        queryWrapper.eq(Order::getIsDelete, "0");
        List<Order> orderList = list(queryWrapper);
        List<OrderVo> orderVoList = new ArrayList<>();
        if (orderList != null && orderList.size() > 0) {
            for (Order order : orderList) {
                OrderVo orderVo = new OrderVo();
                orderVo.setOrderId(order.getId());
                BeanUtils.copyProperties(order, orderVo);
                List<OrderItem> orderItems = orderItemMapper.selectList(Wrappers.<OrderItem>lambdaQuery().eq(OrderItem::getOrderId, order.getId()));
                orderVo.setOrderItemList(orderItems);
                orderVoList.add(orderVo);
            }
        }
        orderVoList.sort(new Comparator<OrderVo>() {
            @Override
            public int compare(OrderVo o1, OrderVo o2) {
                return o2.getCreateTime().compareTo(o1.getCreateTime());
            }
        });
        return ResponseResult.okResult(orderVoList);
    }

    @Override
    public ResponseResult loadOne(String orderId) {
        User user = AppThreadLocalUtils.get();
        if (user == null || user.getId() == null || user.getUsername() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        String username = user.getUsername();
        if (StringUtils.isEmpty(orderId)) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        Order order = getById(orderId);
        if (order == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.ORDER_NOT_EXIST);
        }
        List<OrderItem> orderItems = orderItemMapper.selectList(Wrappers.<OrderItem>lambdaQuery().eq(OrderItem::getOrderId, order.getId()));
        if (orderItems == null || orderItems.size() == 0) {
            return ResponseResult.errorResult(AppHttpCodeEnum.ORDER_ERROR);
        }
        OrderVo orderVo = new OrderVo();
        BeanUtils.copyProperties(order, orderVo);
        orderVo.setOrderId(order.getId());
        orderVo.setOrderItemList(orderItems);
        return ResponseResult.okResult(orderVo);
    }

    @Override
    public ResponseResult closeOrder(String orderId) {
        User user = AppThreadLocalUtils.get();
        if (user == null || user.getId() == null || user.getUsername() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        String username = user.getUsername();
        if (StringUtils.isEmpty(orderId)) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        Order order = getById(orderId);
        if (order == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.ORDER_NOT_EXIST);
        }
        if (order.getPayStatus().equals("1")) {
            return ResponseResult.errorResult(AppHttpCodeEnum.ORDER_PAYED);
        }
        if (order.getOrderStatus().equals("1")) {
            return ResponseResult.errorResult(AppHttpCodeEnum.ORDER_COMPLETE);
        }
        Date createTime = order.getCreateTime();
        long createTimeLong = createTime.getTime();
        long nowTime = System.currentTimeMillis();
        Date closeDate = new Date();
        if (nowTime - createTimeLong >= 15 * 60000) {
            update(Wrappers.<Order>lambdaUpdate().set(Order::getOrderStatus, "3")
                    .set(Order::getPayStatus, "3")
                    .set(Order::getCloseTime, closeDate).eq(Order::getId, orderId));
            List<OrderItem> orderItems = orderItemMapper.selectList(Wrappers.<OrderItem>lambdaQuery().eq(OrderItem::getOrderId, order.getId()));
            for (OrderItem orderItem : orderItems){
                goodsFeign.incrCount(orderItem);
            }
        } else {
            return ResponseResult.errorResult(AppHttpCodeEnum.ORDER_NO_TIME_OUT);
        }
        return ResponseResult.okResult(closeDate);
    }

    @Override
    public ResponseResult deleteOrder(String orderId) {
        User user = AppThreadLocalUtils.get();
        if (user == null || user.getId() == null || user.getUsername() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        String username = user.getUsername();
        if (StringUtils.isEmpty(orderId)) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        Order order = getById(orderId);
        if (order == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.ORDER_NOT_EXIST);
        }
        if ((order.getPayStatus().equals("3") && order.getOrderStatus().equals("3"))
                || (order.getOrderStatus().equals("1") && System.currentTimeMillis() - (order.getEndTime().getTime()) > (15 * 24 * 60 * 60))
                || (order.getOrderStatus().equals("2") && System.currentTimeMillis() - (order.getUpdateTime().getTime()) > (15 * 24 * 60 * 60))) {

            order.setIsDelete("1");
            order.setUpdateTime(new Date());

            updateById(order);

            return ResponseResult.errorResult(AppHttpCodeEnum.SUCCESS);
        }
        return ResponseResult.errorResult(AppHttpCodeEnum.ORDER_DO_NOT_DELETE);
    }

    @Override
    public ResponseResult cancelOrder(String orderId) {
        User user = AppThreadLocalUtils.get();
        if (user == null || user.getId() == null || user.getUsername() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        String username = user.getUsername();
        if (StringUtils.isEmpty(orderId)) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        Order order = getById(orderId);
        if (order == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.ORDER_NOT_EXIST);
        }
        if (order.getPayStatus().equals("1")) {
            return ResponseResult.errorResult(AppHttpCodeEnum.ORDER_PAYED);
        }
        if (order.getOrderStatus().equals("1")) {
            return ResponseResult.errorResult(AppHttpCodeEnum.ORDER_COMPLETE);
        }
        order.setPayStatus("3");
        order.setOrderStatus("3");
        order.setCloseTime(new Date());
        order.setUpdateTime(new Date());
        updateById(order);

        List<OrderItem> orderItems = orderItemMapper.selectList(Wrappers.<OrderItem>lambdaQuery().eq(OrderItem::getOrderId, order.getId()));
        for (OrderItem orderItem : orderItems){
            goodsFeign.incrCount(orderItem);
        }
        redisTemplate.boundHashOps(OrderConstants.ORDERLIST).delete(order.getId());
        if (!order.getPrefId().equals("0")){
            Object userPrefObj = redisTemplate.boundHashOps(CartConstants.RECEIVER_PREF + order.getUsername()).get(order.getPrefId());
            if (userPrefObj != null){
                UserPref userPref = JSON.parseObject(userPrefObj.toString(),UserPref.class);
                redisTemplate.boundHashOps(CartConstants.RECEIVER_PREF + order.getUsername()).put(order.getPrefId(), JSON.toJSONString(userPref));
            }
        }
        return ResponseResult.okResult(order);
    }

    @Override
    public ResponseResult goods(String orderId) {
        User user = AppThreadLocalUtils.get();
        if (user == null || user.getId() == null || user.getUsername() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        String username = user.getUsername();
        if (StringUtils.isEmpty(orderId)) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        Order order = getById(orderId);
        if (order == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.ORDER_NOT_EXIST);
        }
        if (!order.getPayStatus().equals("1")) {
            return ResponseResult.errorResult(AppHttpCodeEnum.ORDER_NOT_PAY);
        }
        if (order.getOrderStatus().equals("1")) {
            return ResponseResult.errorResult(AppHttpCodeEnum.ORDER_COMPLETE);
        }
        if (order.getOrderStatus().equals("3")) {
            return ResponseResult.errorResult(AppHttpCodeEnum.GOODS_RETURNED);
        }
        if (!order.getIsReturn().equals("0")) {
            return ResponseResult.errorResult(AppHttpCodeEnum.RETURNING);
        }
        order.setConsignStatus("2");
        order.setOrderStatus("1");
        order.setEndTime(new Date());
        order.setUpdateTime(new Date());
        updateById(order);

        return ResponseResult.okResult(order);
    }

    @Override
    public ResponseResult getNoReadOrderNotice() {
        User user = AppThreadLocalUtils.get();
        if (user == null || user.getId() == null || user.getUsername() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        String username = user.getUsername();
        Object o = redisTemplate.boundHashOps(OrderConstants.NO_READ_ORDER_NOTICE).get(username);
        if (o == null){
            return ResponseResult.okResult(0);
        }
        Long count = Long.valueOf(String.valueOf(o));
        return ResponseResult.okResult(count);
    }

    @Override
    public ResponseResult getOrderNotice() {
        User user = AppThreadLocalUtils.get();
        if (user == null || user.getId() == null || user.getUsername() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        String username = user.getUsername();
        List<Object> values = redisTemplate.boundHashOps(OrderConstants.ORDER_NOTICE_USER + username).values();
        if (values == null || values.size() == 0){
            return ResponseResult.errorResult(AppHttpCodeEnum.NO_NOTICE);
        }
        List<OrderNotice> orderNotices = JSON.parseArray(values.toString(), OrderNotice.class);
        orderNotices.sort(new Comparator<OrderNotice>() {
            @Override
            public int compare(OrderNotice o1, OrderNotice o2) {
                return o2.getCreateTime().compareTo(o1.getCreateTime());
            }
        });
        return ResponseResult.okResult(orderNotices);
    }

    @Override
    public ResponseResult read() {
        User user = AppThreadLocalUtils.get();
        if (user == null || user.getId() == null || user.getUsername() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        String username = user.getUsername();
        List<Object> values = redisTemplate.boundHashOps(OrderConstants.ORDER_NOTICE_USER + username).values();
        if (values == null || values.size() == 0){
            return ResponseResult.errorResult(AppHttpCodeEnum.NO_NOTICE);
        }
        List<OrderNotice> orderNotices = JSON.parseArray(values.toString(), OrderNotice.class);
        for (OrderNotice orderNotice : orderNotices){
            if (orderNotice.getState().equals("0")){
                orderNotice.setState("1");
                redisTemplate.boundHashOps(OrderConstants.ORDER_NOTICE_USER  + username).put(orderNotice.getOrderId(),JSON.toJSONString(orderNotice));
            }
        }
        redisTemplate.boundHashOps(OrderConstants.NO_READ_ORDER_NOTICE).delete(username);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }


    public void convertAndSend(String orderId) {
        rabbitTemplate.convertAndSend(env.getProperty(AMQPConstants.MQ_ORDER_QUEUE_ORDERTIMERDELAY), (Object) ("order," + orderId),
                new MessagePostProcessor() {
                    @Override
                    public Message postProcessMessage(Message message) throws AmqpException {
                        System.out.println("发送订单超时消息");
                        message.getMessageProperties().setExpiration("60000");
                        return message;
                    }
                });
        rabbitTemplate.convertAndSend("order_timer_notice_delay_queue", (Object) ("order,"+orderId), new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                System.out.println("发送提醒支付消息");
                message.getMessageProperties().setExpiration("10000");
                return message;
            }
        });
    }

    public void noticeConverAndSend(String orderId){
       /* rabbitTemplate.convertAndSend(env.getProperty(AMQPConstants.MQ_ORDER_QUEUE_ORDERTIMERDELAY), (Object) ("order," +orderId) , new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                System.out.println("发送订单超时消息");
                message.getMessageProperties().setExpiration("60000");
                return message;
            }
        });*/
    }
}
